﻿#region File Description
//Terrain.cs
// norm = (dy, -dx) or (-dy, dx) <-One Used
//**All terrain is defined in a counter-clockwise fashion
//Terrain can be instansiated as a list of vectors or lines, with the structure linesegment being public
//To test if a collision rectangle is encountering the line, call IsColliding
//If there is a collision terrain's public member normalVector will be set for the object
//
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace Squog_1._1
{ 
    public class Terrain
    {
       
        #region Members

        //private List<Texture2D> textures;
        private List<Vector2> vertices;
        private List<LineSegment> lineSegments;

        #endregion

        #region Initilization

        public Terrain(List<LineSegment> lineSegs)
        {
            lineSegments = lineSegs;
        }

        public Terrain(List<Vector2> verts)
        {
            lineSegments = CreateLineSegments(verts);
        }

        #endregion

        #region Methods

        public List<LineSegment> CreateLineSegments(List<Vector2> verts)
        {
            vertices = verts;

            List<LineSegment> lineSegments = new List<LineSegment>();

            for (int i = 0; i < vertices.Count-1; i++)
            {
                LineSegment lineSegment = new LineSegment(vertices[i], vertices[i + 1]);
                lineSegments.Add(lineSegment);
            }

            return lineSegments;
        }

        public List<LineSegment> IsColliding(Rectangle collisionRect)
        {
            List<LineSegment> collisionLineSegments = new List<LineSegment>();
            LineSegment north = new LineSegment(new Vector2(collisionRect.X, collisionRect.Y), new Vector2(collisionRect.X + collisionRect.Width, collisionRect.Y));
            LineSegment east = new LineSegment(new Vector2(collisionRect.X+collisionRect.Width, collisionRect.Y), new Vector2 (collisionRect.X+collisionRect.Width, collisionRect.Y+collisionRect.Height));
            LineSegment south = new LineSegment(new Vector2 (collisionRect.X+collisionRect.Width, collisionRect.Y+collisionRect.Height), new Vector2(collisionRect.X, collisionRect.Y+collisionRect.Height));
            LineSegment west = new LineSegment(new Vector2(collisionRect.X, collisionRect.Y+collisionRect.Height), new Vector2(collisionRect.X, collisionRect.Y));

            foreach(LineSegment lineSegment in lineSegments)
            {
                if(LineIntersectsLine(lineSegment, north) || LineIntersectsLine(lineSegment, east) || LineIntersectsLine(lineSegment, south) || LineIntersectsLine(lineSegment, west))
                {
                    collisionLineSegments.Add(lineSegment);
                }
            }

            return collisionLineSegments;
        }

        private static bool LineIntersectsLine(LineSegment lineSeg, LineSegment rectLine)//i haven't figured out why this works, need to be tested
        {
            Vector2 L1P1 = lineSeg.point1;
            Vector2 L1P2 = lineSeg.point2;
            Vector2 L2P1 = rectLine.point1;
            Vector2 L2P2 = rectLine.point2;

            float q = (L1P1.Y - L2P1.Y) * (L2P2.X - L2P1.X) - (L1P1.X - L2P1.X) * (L2P2.Y - L2P1.Y);
            float d = (L1P2.X - L1P1.X) * (L2P2.Y - L2P1.Y) - (L1P2.Y - L1P1.Y) * (L2P2.X - L2P1.X);

            if (d == 0)
            {
                return false;
            }

            float r = q / d;
            q = (L1P1.Y - L2P1.Y) * (L1P2.X - L1P1.X) - (L1P1.X - L2P1.X) * (L1P2.Y - L1P1.Y);
            float s = q / d;

            if (r < 0 || r > 1 || s < 0 || s > 1)
            {
                return false;
            }
            
            return true;
        }

        public List<LineSegment> GetLines()
        {
            return lineSegments;
        }

        #endregion
    }
}
